<?php

namespace app\common\library;

use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * 导出excel class
 * @author daichongweb
 */
class Export
{
    // 表格坐标
    private $cellIndex = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ', 'BA', 'BB', 'BC'];

    // 默认配置
    public $config = [
        'bold' => true, // 加粗
        'size' => 12, // 文字大小
        'column' => 4, // 设置列数
        'title' => '工作表', // 表格标题
        'name' => '特抱抱', // 文件名
        'type' => 'Xlsx', // 导出格式
    ];

    // 默认表头
    public $tableHeader = [
        'php',
        'vue',
        'java',
        'go',
    ];

    // 默认数据
    public $tableDefaultData = [
        [
            '天下第一',
            'Vue牛逼',
            'java牛逼',
            'go牛逼',
        ],
    ];

    protected $exportWay = 'download';

    /**
     * @param array $tableHeader 表头
     * @param array $tableDefaultData 需要导出数据
     */
    public function __construct($tableHeader, $tableDefaultData, $filename, $exportWay = 'download')
    {
        $this->setParams($tableHeader, $tableDefaultData, $filename, $exportWay);
    }

    public function setParams($tableHeader, $tableDefaultData, $filename, $exportWay = 'download')
    {
        if (empty($tableHeader)) {
            throw new Exception('export error: 请设置表头');
        }
        /*
        if (empty($tableDefaultData)) {
            throw new Exception('export error: 请设置导出数据');
        }
         */

        $this->tableHeader = $tableHeader;
        $this->config['column'] = count($tableHeader);
        $this->config['name'] = $filename;
        $this->tableDefaultData = $tableDefaultData;
        $this->exportWay = $exportWay;
    }

    /**
     * 创建表格 createTable
     */
    public function createTable()
    {
        $spreadsheet = new Spreadsheet();
        $worksheet = $spreadsheet->getActiveSheet();

        //居中
        $styleArray = [
            'alignment' => [
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
            ],
        ];

        // 设置基本属性
        $worksheet->setTitle($this->config['title']);
        $worksheet->getStyle($this->getColumn())->applyFromArray($styleArray)
            ->getFont()
            ->setBold($this->config['bold'])
            ->setName('Verdana')
            ->setSize($this->config['size']);

        foreach ($this->tableHeader as $index => $name) {
            $worksheet->setCellValue($this->cellIndex[$index] . '1', $name);
        }

        $baseRow = 2;
        foreach ($this->tableDefaultData as $index => $data) {
            $i = $index + $baseRow;
            for ($k = 0; $k <= $this->config['column'] - 1; $k++) {
                if (isset($data[$k])) {
                    $item = $data[$k];
                    $worksheet->setCellValue($this->cellIndex[$k] . $i, ' ' . $item);
                    // 中文设置表格宽度
                    if (preg_match("/[\x7f-\xff]/", $data[$k])) {
                        $worksheet->getColumnDimension($this->cellIndex[$k])->setWidth(strlen($item));
                    } else {
                        // 非中文自动设置宽度
                        $worksheet->getColumnDimension($this->cellIndex[$k])->setAutoSize(true);
                    }
                }
            }
        }
        $worksheet->calculateColumnWidths();
        self::downloadExcel($spreadsheet, $this->config['name'], 'Xlsx');
    }

    /**
     * 文件下载 downloadExcel
     *
     * @param data $spreadsheet
     * @param string $filename
     * @param string $format
     * @return void
     */
    private function downloadExcel($spreadsheet, $filename, $format)
    {
        if ($this->exportWay == 'download') {
            $arr = explode('/', $filename);
            $filename = $arr[count($arr) - 1];
            // $format只能为 Xlsx 或 Xls
            if ($format == 'Xlsx') {
                header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            } elseif ($format == 'Xls') {
                header('Content-Type: application/vnd.ms-excel');
            }
            header("Content-Disposition: attachment;filename=". urlencode($filename));
            header('Cache-Control: max-age=0');
            $objWriter = IOFactory::createWriter($spreadsheet, $format);
            $objWriter->save('php://output');
            exit;
        } else if ($this->exportWay == 'save') {
            $writer = new Xlsx($spreadsheet);
            $writer->save($filename);
        }
    }

    private function getColumn($row = 1)
    {
        $index = $this->cellIndex[$this->config['column']];
        return 'A' . $row . ':' . $index . $row;
    }

    private function autoFitColumnWidthToContent($sheet, $fromCol, $toCol)
    {
        if (empty($toCol)) { //not defined the last column, set it the max one
            $toCol = $sheet->getColumnDimension($sheet->getHighestColumn())->getColumnIndex();
        }
        for ($i = $fromCol; $i <= $toCol; $i++) {
            $sheet->getColumnDimension($i)->setAutoSize(true);
        }
        $sheet->calculateColumnWidths();
    }
}
